package com.cscec5b.inspection.controller;

import com.cscec5b.inspection.config.AppProperties;
import com.cscec5b.inspection.config.JwtService;
import com.cscec5b.inspection.config.KeyManager;
import com.cscec5b.inspection.dto.TokenDtos.TokenRequest;
import com.cscec5b.inspection.dto.TokenDtos.TokenResponse;
import com.cscec5b.inspection.entity.ClientApp;
import com.cscec5b.inspection.repository.ClientRepository;
import com.nimbusds.jose.jwk.JWKSet;
import jakarta.validation.Valid;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.Map;

@RestController
public class AuthController {
    private final ClientRepository clientRepo;
    private final JwtService jwtService;
    private final AppProperties props;
    private final KeyManager keyManager;

    public AuthController(ClientRepository clientRepo, JwtService jwtService, AppProperties props, KeyManager keyManager) {
        this.clientRepo = clientRepo; this.jwtService = jwtService; this.props = props; this.keyManager = keyManager;
    }

    @PostMapping(value="/auth/token", consumes=MediaType.APPLICATION_JSON_VALUE)
    public TokenResponse token(@RequestBody @Valid TokenRequest req) {
        if (!"client_credentials".equals(req.grant_type)) throw new IllegalArgumentException("unsupported grant_type");
        ClientApp app = clientRepo.findByClientId(req.client_id)
                .filter(ClientApp::isActive).orElseThrow(() -> new RuntimeException("invalid client_id"));
        if (!app.getClientSecret().equals(req.client_secret)) throw new RuntimeException("bad client_secret");

        String requestScope = (req.scope == null || req.scope.isBlank()) ? "user.sync" : req.scope;
        if (!Arrays.asList(app.getScopes().split(" ")).containsAll(Arrays.asList(requestScope.split(" "))))
            throw new RuntimeException("scope not allowed");

        String jwt = jwtService.issueToken(app.getClientId(), Arrays.asList(requestScope.split(" ")));
        return new TokenResponse(jwt, props.getTokenTtlSeconds());
    }

    @GetMapping("/.well-known/jwks.json")
    public Map<String, Object> jwks() { return new JWKSet(keyManager.currentJwk()).toJSONObject(); }


}
